home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
program
/
tjgold.zip
/
INSTALL.001
/
GOLDFAST.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-07-12
|
83KB
|
2,779 lines
{--------------------------------------------------------------------------}
{ Product: TechnoJock's Turbo Toolkit }
{ Version: GOLD }
{ Build: 1.01 }
{ }
{ Copyright 1986-1995 TechnoJock Software, Inc. }
{ All Rights Reserved }
{ Restricted by License }
{--------------------------------------------------------------------------}
{**********************************}
{** Unit: GOLDFAST **}
{**********************************}
{++++++++++++++++++++++++++++++} unit GOLDFAST; {++++++++++++++++++++++++++++}
{$I GOLDFLAG.INC}
{$IFNDEF GOLDFAST}
{$DEFINE GOLDFAST}
{$ENDIF}
{++++++++++++++++++++++++++++++++} INTERFACE {+++++++++++++++++++++++++++++++}
uses DOS, CRT,
GoldReal, GoldAttr, GoldHard, GoldTint, GoldMisc, GoldStr;
const
MaxVirtualScreens = 5; {Change this constant as necessary}
MaxButLen = 20; {Change this constant as necessary}
InternalScreen1 = succ(MaxVirtualScreens);
InternalScreen2 = succ(InternalScreen1);
InternalScreen3 = succ(InternalScreen2);
DefCol:byte = 255;
Plain: byte = 0;
FirstWinCol = WinBorder; {Start value in WinTints}
LastWinCol = WinBorderOff;
WinConfine = 6; {restrict screen writes to WX1..WY2}
{$IFNDEF DPMI}
SegB000:word = $B000;
SegB800:word = $B800;
{$ENDIF}
{$IFDEF TTT5}
FCol:byte = white;
BCol:byte = black;
{$ENDIF}
type
StrScreen = string[80];
StrButton = string[MaxButLen];
VideoWord = record
Ch : char;
Attr : byte;
end;
gVideoTarget = (WinTarget,ScreenTarget);
gDirection = (Up,Down,Left,Right,Vert,Horiz);
WinTints = array[FirstWinCol..LastWinCol] of byte;
ScrollType = (NoScroll,HorizScroll,VertScroll,BothScroll);
VideoZone = record
ScreenPtr: pointer; {pointer to display memory}
Width: byte; {screen or window width}
Depth:byte; {screen or window depth}
WX1,WY1,WX2,WY2 : byte; {local window coordinates}
WindowActive: boolean; {writes confined within window?}
TargetType: gVideoTarget; {window or screen}
TargetPtr: pointer; {pointer to screen or window structure}
MoveCursor: boolean; {is it top window or main screen}
end;
ScreenInfoPtr = ^ScreenInfo;
ScreenInfo = record
Width: byte; {how wide is screen}
Depth:byte;
CursorX: byte;
CursorY: byte;
ScanTop: byte;
ScanBot: byte;
Window: gByteCoords; {active screen area}
WindowIgnore: boolean; {ignore window settings}
ScreenPtr: pointer;
end;
StretchProc = procedure (X1,Y1,X2,Y2:byte);
WinKeyHandler = procedure;
WinCloseProc = function(Handle:integer):boolean;
WinChangeFocusProc = procedure(Handle:integer);
CursorInfo = record
X: byte; {saved cursor location}
Y: byte; {saved -"- }
Top: byte; {saved cursor size}
Bot: byte; {saved -"- }
end;
WStructurePtr = ^WStructure;
WStructure = record
{The first six fields are access by ASM code -- do not change}
SurfacePtr: pointer; {ptr to window image}
Width: byte;
Depth: byte;
X: shortint; {can go negative if window dragged leftward}
Y: shortint; {can go negative if window dragged upward}
NextWinPtr: WStructurePtr;
{local (non-ASM) data follows}
WinStyle: byte; {window appearance}
WinState: byte; {bit flags for allowclose, allowmove, etc}
Title: StrScreen; {window title}
Col: WinTints; {display colors}
WinNum: byte; {window number}
WinX1, {writing/scrolling area within window}
WinY1,
WinX2,
WinY2: byte;
UserData:pointer; {user-defined info}
{moveable windows}
Boundary: gCoords; {max area in which window can move}
{Scrollable}
Scroll: ScrollType; {are scroll bars supported}
{Stretch}
MinWidth: byte; {min width of SmartWin}
MinDepth: byte; {min depth of SmartWin}
StretchCallBack: StretchProc; {to refresh window during stretch}
{Internals}
Cursor: CursorInfo; {state of cursor}
PreZoom: gCoords; {size of window in Unzoomed state}
Painted: boolean; {has window already been painted}
ProcessKeyProc: WinKeyHandler; {used in the desktop}
CloseWinProc: WinCloseProc; { -"- }
ChangeFocusProc: WinChangeFocusProc; { -"- }
end; {WStructure}
FastSet = record
ECode: integer;
{scroll bar data}
UpArrowChar: char;
DownArrowChar: char;
LeftArrowChar: char;
RightArrowChar: char;
ElevatorChar: char;
BackgroundChar: char;
{progress bar data}
ProgChar1: char;
ProgChar2: char;
PerCentPad: byte;
PerCentColor: byte;
{screen}
ActiveScreen: shortint;
Screen : array[0..InternalScreen3] of ScreenInfoPtr;
{startup details}
StartMode: word;
StartTop: byte;
StartBot: byte;
StartX: byte;
StartY: byte;
{misc}
CustomCharsActive: boolean;
ExitChain: pointer;
GrowNoise: boolean;
EMsgFunc: ErrMsgFunc;
end; {FastSet}
var
FastVars: FastSet;
VideoTarget: VideoZone;
SnowProne : boolean; {used by Asm code}
LineWrap: boolean; { " }
ShowNow: boolean; { " }
ScreenLines: byte; { " }
WinList: pointer; { " }
BackBuffer: pointer; { " }
FrontBuffer: pointer; { " }
ShadowAttr: byte; { " }
ShadowType: byte; { " }
WinX: byte; {Asm scratch data}
WinY: byte; { " }
WinWidth0: word; { " }
WinWidth: word; { " }
WinDepth0: word; { " }
WinDepth: word; { " }
WinOff: word; { " }
SourceIncr: word; { " }
TargetIncr: word; { " }
Windex: word; { " }
PaneWidth: word; { " }
PaneDepth: word; { " }
PaneOff: word; { " }
PaneType: byte; { " }
CRFlag: byte; { " }
WriteDepth: byte; { " }
BBTop: byte; { " }
BBBot: byte; { " }
FrontUpdated: boolean;
function LastFastError: integer;
function OnScreen:boolean;
procedure ResetStartUpMode;
{window routines}
procedure SetWindow(X1,Y1,X2,Y2: byte);
function GetSetWinIgnore(On:Boolean):boolean;
procedure SetWinIgnore(On:Boolean);
procedure ResetWindow;
{cursor routines}
procedure CursorFind(var X,Y,Top,Bot:byte);
procedure AbsGotoXY(X,Y:byte);
procedure GotoXY(X,Y:byte);
procedure AbsWhereXY(var X,Y:byte);
function WhereX: byte;
function WhereY: byte;
function CharHeight: integer;
procedure CursorAbsSize(T,B:byte);
procedure CursorSize(T,B:byte);
procedure CursorHalf;
procedure CursorFull;
procedure CursorOff;
procedure CursorOn;
{screen routines}
procedure ActivateVirtualScreen(Page:word);
procedure ActivateVisibleScreen;
procedure ActivateBackground;
procedure CreateScreen(Page,X,Y,FB:byte);
procedure SaveScreen(Page:byte);
procedure PartRestoreScreen(Page,X1,Y1,X2,Y2,X,Y:byte);
procedure SlideRestoreScreen(Page:byte;Way:gDirection);
procedure PartSlideRestoreScreen(Page:byte;Way:gDirection;X1,Y1,X2,Y2:byte);
procedure RestoreScreen(Page:byte);
procedure DisposeScreen(Page:byte);
procedure CopyScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
procedure MoveScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
procedure Scroll(Way:gDirection;X1,Y1,X2,Y2:byte);
{screen writing}
procedure FillScreen(X1,Y1,X2,Y2:byte; FB:byte; C:char);
procedure Clear(FB:byte; C:Char);
procedure PartClear(X1,Y1,X2,Y2:byte; FB:byte; C:char);
procedure WritePlain(X,Y:byte; St:string);
procedure WriteAT(X,Y,FB:byte; St:string);
procedure WriteCol(Col,Row:byte; St:string);
procedure WriteCap(X,Y,FBCap,FB:byte;Str:string);
procedure WriteHi(X,Y,HiFB,FB:byte;Str:string);
procedure WriteHiX2(X1,X2,Y,HiFB,FB:byte;Str:string);
procedure WriteHiCenter(Y,HiFB,FB:byte;Str:string);
procedure WriteClick(X,Y,FB:byte;Str:string);
procedure WriteCenter(Y,FB:byte;Str:string);
procedure WriteMiddle(X,FB:byte;Str:string);
procedure WriteBetween(X1,X2,Y,FB:byte;Str:string);
procedure WriteRight(X,Y,FB:byte;Str:string);
procedure WriteVert(X,Y,FB:byte;Str:string);
procedure WriteProgressLong(X1,X2,Y:byte;Part,Total:longint;ShowPerCent:boolean);
procedure WriteProgressReal(X1,X2,Y:byte;Part,Total:extended;ShowPerCent:boolean);
procedure Attrib(X1,Y1,X2,Y2,FB:byte);
procedure ClearText(X1,Y1,X2,Y2,FB:byte);
procedure ClearLine(Y,FB:integer);
{screen reading}
procedure ReadWord(X,Y:byte;var Attr:byte; var Ch : char);
function ReadChar(X,Y:byte):char;
function ReadAttr(X,Y:byte):byte;
function ReadStr(X1,X2,Y:byte):string;
{box and line drawing}
procedure Box(X1,Y1,X2,Y2,FB,style:byte);
procedure FBox(X1,Y1,X2,Y2,FB,style:byte);
procedure GrowFBox(X1,Y1,X2,Y2,FB,style:byte);
procedure Box3D(X1,Y1,X2,Y2:byte;TLFB,BRFB,Style:byte);
procedure HorizLine(X1,X2,Y,FB,Style : byte);
procedure VertLine(X,Y1,Y2,FB,Style:byte);
procedure SmartVertLine(X,Y1,Y2,FB,Style:byte);
procedure SmartHorizLine(X1,X2,Y,FB,Style:byte);
{shadow routines}
procedure DrawShadow(X1,Y1,X2,Y2:integer);
procedure OuterXY(var X1,Y1,X2,Y2: integer);
{display routines}
procedure SetCondensed;
procedure Set25;
procedure SetBlinking(On:boolean);
{scroll bars}
procedure SetScrollChars(U,D,L,R,E,B:char);
procedure SetScrollDefaults;
function GetHScrollBarElevator(X1,X2:byte;Current,Max:longint) : byte;
function GetVScrollBarElevator(Y1,Y2:byte;Current,Max:longint) : byte;
procedure WriteHScrollBar(X1,X2,Y,FB: byte; Current,Max: longint);
procedure WriteVScrollBar(X,Y1,Y2,FB: byte; Current,Max: longint);
{custom ASCII characters}
{$IFNDEF NOVGACHARS}
function CustomCapable: boolean;
procedure UseCustomChars;
procedure UseCustomFunctionKeys;
procedure RemoveCustomChars;
{$ENDIF} {NOVGACHARS}
{internal procedures used by other toolkit units}
procedure CursorPos(X,Y: integer);
procedure WinWrite(var WinImage; Width,X1,Y2,X2,Y2,X3,Y3,Attr:byte; St:string;WWIgnore:byte);
procedure WinPlain(var WinImage; Width,X1,Y2,X2,Y2,X3,Y3,Attr:byte; St:string;WWIgnore:byte);
procedure WinAttr(var WinImage; Width,X1,Y2,X2,Y2,X3,Y3,X4,Y4,Attr:byte;WWIgnore:byte);
procedure WinDrawAll;
procedure WinDrawTop;
procedure FillVideo(var Buffer; Count:word; Info:VideoWord);
procedure MoveToScreen(SourceY1,SourceX1,SourceY2,SourceX2,SourceWidth:byte;var SourcePtr;
TargetX,TargetY,TargetWidth:byte;var TargetPtr);
procedure MoveFromScreen(X1,Y1,X2,Y2,SourceWidth:byte; var SourcePtr, TargetPtr);
function Different(var Source1,Source2;Size:word):boolean;
procedure WinRedraw(MakeVisible:boolean);
procedure DrawButton(X1,X2,Y,HiFB,FB:byte; Str:string);
procedure DrawButtonDown(X1,X2,Y,HiFB,FB:byte; Str:string);
procedure PartSave (X1,Y1,X2,Y2:byte; VAR Dest);
procedure PartRestore (X1,Y1,X2,Y2:byte; VAR Source);
{$IFDEF TTT5}
procedure FastWrite(Col,Row,Attr:byte; St:StrScreen);
procedure FWrite(St:StrScreen);
procedure FWriteLN(St:StrScreen);
function EGAVGASystem: boolean;
procedure SetCondensedLines;
procedure Set25Lines;
procedure Activate_Visible_Screen;
procedure Activate_Virtual_Screen(Page:byte);
procedure Reset_StartUp_Mode;
function GetScreenChar(X,Y:byte):char;
function GetScreenAttr(X,Y:byte):byte;
procedure GetScreenStr(X1,X2,Y:byte;var St:StrScreen);
procedure PlainWrite(X,Y:byte; St:string);
procedure FBAttrib(X1,Y1,X2,Y2,F,B:byte);
procedure FBClickwrite(Col,Row,F,B:byte; St:StrScreen);
procedure FBBox(X1,Y1,X2,Y2,F,B,boxtype:integer);
procedure FBFBox(X1,Y1,X2,Y2,F,B,boxtype:integer);
procedure FBGrowFBox(X1,Y1,X2,Y2,F,B,boxtype:integer);
procedure FBHorizLine(X1,X2,Y,F,B,lineType:byte);
procedure FBVertLine(X,Y1,Y2,F,B,lineType:byte);
procedure FBClearText(x1,y1,x2,y2,F,B:integer);
procedure FBClearLine(Y,F,B:integer);
procedure FBWriteAT(X,Y,F,B:integer; St:StrScreen);
procedure FBWriteBetween(X1,X2,Y,F,B:byte; St:StrScreen);
procedure FBWriteCenter(LineNO,F,B:integer; St:StrScreen);
procedure FBWriteVert(X,Y,F,B:integer; St:StrScreen);
procedure FBFillScreen(X1,Y1,X2,Y2:byte; F,B:byte; C:char);
{$ENDIF}
{+++++++++++++++++++++++++++++} IMPLEMENTATION {+++++++++++++++++++++++++++++}
uses GoldKey;
const
MaxVScreens = InternalScreen3; {3 screens are used internally}
ShadWidth = 2;
ShadDepth = 1;
{$IFNDEF NOVGACHARS}
(*
Notes: The following contains the code for using custom ASCII
characters on VGA systems.
The replacment characters come in two categories: characters
which need to touch the adjacent character, known as "wide"
characters, and regular characters.
The wide fonts must be located in the region 192 to 223 of
the 256 ASCII characters. DOS assumes that all characters
outside of this region will not be joined.
To avoid using characters required in normal text, Gold
sacrifices double line-drawing characters and replaces
them with custom characters. In otherwords, you can't
have the custom fonts and double line boxes.
The following custom characters are provided:
Line Drawing:
Single line box drawing characters where the line is
on the outside of the box
Thin line characters for chisel/indentation effects
Single Character Icons
Check Mark (Tick for you Brits}
Function keys F1 to F12
Double Character Icons
Close Window
Check box - empty
Check box - selected
Radio button - empty
Radio button - selected
Maximize Window
Normalize Windows
*)
const
CharSize = 16;
WideCharCount = 19;
WideCharStart = 198; {to 216}
Wide2CharCount = 2;
Wide2CharStart = 221;
RegularCharCount = 9;
RegularCharStart = 181;
Regular2CharCount = 12;
Regular2CharStart = 224;
type
WideCharBuffer = array[1..WideCharCount*CharSize] of byte;
Wide2CharBuffer = array[1..Wide2CharCount*CharSize] of byte;
RegularCharBuffer = array[1..RegularCharCount*CharSize] of byte;
Regular2CharBuffer = array[1..Regular2CharCount*CharSize] of byte;
{$IFNDEF DPMI}
const
WideChars: WideCharBuffer =
(
{$IFDEF THINLINES}
$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$FF, {198 - bottom left corner}
$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$FF, {199 - bottom right corner}
$FF,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01, {200 - top right corner}
$FF,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0, {201 - top left corner}
$FF,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00, {202 - top}
$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF, {203 - bottom}
$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01, {204 - rightvert}
{$ELSE}
$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$FF,$FF, {198 - bottom left corner}
$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$FF,$FF, {199 - bottom right corner}
$FF,$FF,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03, {200 - top right corner}
$FF,$FF,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0, {201 - top left corner}
$FF,$FF,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00, {202 - top}
$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF, {203 - bottom}
$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03, {204 - rightvert}
{$ENDIF}
$FF,$80,$80,$80,$81,$83,$87,$80,$80,$87,$83,$81,$80,$80,$80,$FF, {205 - normalize left}
$FF,$80,$80,$80,$80,$80,$80,$9F,$9F,$80,$80,$80,$80,$80,$80,$FF, {206 - winclose left}
$FF,$01,$01,$01,$01,$01,$01,$F9,$F9,$01,$01,$01,$01,$01,$01,$FF, {207 - winclose right}
$00,$07,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$07,$01,$00, {208 - check box left}
$00,$FF,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,$00, {209 - check box middle unchecked}
$00,$FF,$00,$06,$06,$0C,$0C,$18,$98,$F0,$70,$20,$00,$FF,$FF,$00, {210 - check box middle checked}
$00,$00,$00,$01,$02,$02,$04,$04,$04,$04,$02,$02,$01,$00,$00,$00, {211 - radio button left}
$00,$00,$FE,$01,$00,$00,$00,$00,$00,$00,$00,$00,$01,$FE,$00,$00, {212 - radio button middle unselected}
$00,$00,$FE,$01,$00,$7C,$FE,$FE,$FE,$FE,$7C,$00,$01,$FE,$00,$00, {213 - radio button middle selected}
$00,$00,$00,$03,$0C,$10,$20,$20,$20,$20,$10,$0C,$03,$00,$00,$00, {214 - free}
$00,$00,$00,$03,$0C,$11,$23,$27,$27,$23,$11,$0C,$03,$00,$00,$00, {215 - free}
$FF,$01,$01,$01,$01,$81,$C1,$01,$01,$C1,$81,$01,$01,$01,$01,$FF {216 - normlize right}
);
Wide2Chars: Wide2CharBuffer =
(
$FF,$80,$80,$80,$80,$80,$80,$81,$83,$87,$80,$80,$80,$80,$80,$FF, {221 - maximize left}
$FF,$01,$01,$01,$01,$01,$01,$01,$81,$C1,$01,$01,$01,$01,$01,$FF {222 - maximize right}
);
RegularChars: RegularCharBuffer =
(
$80,$C0,$E0,$F0,$F8,$FC,$FE,$F8,$F8,$BC,$1C,$0E,$0C,$00,$00,$00, {181 - mouse cursor arrow}
$03,$03,$03,$06,$06,$06,$0C,$0C,$CC,$CC,$6C,$78,$18,$00,$00,$00, {182 - check mark}
$00,$E0,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$30,$F0,$F0,$00, {183 - check box right}
$00,$00,$00,$00,$80,$80,$40,$40,$40,$40,$80,$80,$00,$00,$00,$00, {184 - radio button right}
$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01, {185 - thin vertical line}
$00,$00,$00,$80,$60,$10,$08,$08,$08,$08,$10,$60,$80,$00,$00,$00, {186 - free}
$00,$00,$00,$80,$60,$10,$88,$C8,$C8,$88,$10,$60,$80,$00,$00,$00, {187 - free}
$FF,$01,$01,$01,$01,$01,$01,$81,$C1,$E1,$01,$01,$01,$01,$01,$FF, {188 - normalize right}
{$IFDEF THINLINES}
$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0,$C0 {189 - left vert}
{$ELSE}
$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0,$E0 {189 - left vert}
{$ENDIF}
);
Regular2Chars: Regular2CharBuffer =
(
$00,$7C,$40,$40,$70,$40,$40,$40,$04,$0C,$04,$04,$04,$04,$0E,$00, {224 - F1}
$00,$7C,$40,$40,$70,$40,$40,$40,$06,$09,$01,$02,$04,$08,$0F,$00, {225 - F2}
$00,$7C,$40,$40,$70,$40,$40,$40,$0F,$01,$01,$02,$01,$09,$06,$00, {226 - F3}
$00,$7C,$40,$40,$70,$40,$40,$40,$08,$08,$0A,$0A,$0F,$02,$02,$00, {227 - F4}
$00,$7C,$40,$40,$70,$40,$40,$40,$0E,$10,$10,$1C,$02,$02,$1C,$00, {228 - F5}
$00,$7C,$40,$40,$70,$40,$40,$40,$0C,$10,$10,$1C,$12,$12,$0C,$00, {229 - F6}
$00,$7C,$40,$40,$70,$40,$40,$40,$1E,$02,$02,$0C,$08,$08,$08,$00, {230 - F7}
$00,$7C,$40,$40,$70,$40,$40,$40,$0C,$12,$12,$0C,$12,$12,$0C,$00, {231 - F8}
$00,$7C,$40,$40,$70,$40,$40,$40,$0C,$12,$12,$0E,$02,$02,$0C,$00, {232 - F9}
$00,$7C,$40,$40,$70,$40,$40,$40,$26,$69,$29,$29,$29,$29,$76,$00, {233 - F10}
$00,$7C,$40,$40,$70,$40,$40,$40,$22,$66,$22,$22,$22,$22,$77,$00, {234 - F11}
$00,$7C,$40,$40,$70,$40,$40,$40,$26,$69,$21,$22,$24,$28,$7F,$00 {235 - F12}
);
{$ENDIF}
(*
var
TwiddleDummy: array[1..64] of byte; {used by TWIDDLE.ASM}
OriginalChars: array[1..4] of byte; {characters that are replaced with Mouse image}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
{$L TWIDDLE}
procedure Twiddle(Y,X:byte; var Curs); external;
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
*)
procedure SetVGAChars(var Fonts; Start,Count:word);
{INTERNAL}
var Regs: registers;
begin
with Regs do
begin
Ah := $11;
Al := $00;
bl := 0;
ES := seg(Fonts);
BP := ofs(Fonts);
CX := Count;
DX := Start;
Bh := CharSize;
end;
intr($10,Regs);
end; { SetVGAChars }
function CustomCapable: boolean;
{}
begin
CustomCapable := HardVars.DisplayType in [VGAMono,VGACol];
end; { CustomCapable }
procedure UseCustomChars;
{Remaps the upper ASCII characters to radio buttons, thin lines, etc}
begin
{$IFNDEF DPMI}
if CustomCapable then
begin
SetVGAChars(WideChars,WideCharStart,WideCharCount);
SetVGAChars(RegularChars,RegularCharStart,RegularCharCount);
FastVars.CustomCharsActive := true;
end;
{$ENDIF}
end; { UseCustomChars }
procedure UseCustomFunctionKeys;
{Remaps some upper ASCII characters to show function keys, etc.}
begin
{$IFNDEF DPMI}
SetVGAChars(Regular2Chars,Regular2CharStart,Regular2CharCount);
{$ENDIF}
end; { UseCustomFunctionKeys }
procedure RemoveCustomChars;
{}
var Regs: registers;
begin
if FastVars.CustomCharsActive then
begin
with Regs do
begin
Ah := $0;
Al := $3;
end;
intr($10,Regs);
FastVars.CustomCharsActive := false;
end;
end; { RemoveCustomChars }
{*******************}
{** Box Drawing **}
{*******************}
procedure Box3D(X1,Y1,X2,Y2:byte;TLFB,BRFB,Style:byte);
{Draws a chiselled 3D box - ensure that background colors are the same}
var CharStr: string[6];
I: integer;
begin
ClearText(X1,Y1,X2,Y2,TLFB);
if (X2-X1 > 4) and (Y2-Y1 > 1) then
begin
if Style <> 2 then
CharStr := '┌─┐│┘└'
else
CharStr := '╔═╗║╝╚';
WritePlain(succ(X1),Y1,CharStr[1]);
WritePlain(X1+2,Y1,replicate(X2-X1-3,CharStr[2]));
WritePlain(succ(X1),Y2,CharStr[6]);
WriteAT(pred(X2),Y1,BRFB,CharStr[3]);
for I := succ(Y1) to pred(Y2) do
begin
WritePlain(succ(X1),I,CharStr[4]);
WriteAT(pred(X2),I,BRFB,CharStr[4]);
end;
WriteAT(pred(X2),Y2,BRFB,CharStr[5]);
WriteAT(X1+2,Y2,BRFB,replicate(X2-X1-3,CharStr[2]));
end;
end; { Box3D }
{ Styles:
1 - Single Line Border - Standard
2 - Double Line Border
3 - Title Bar (caption)
4 - Edge Border w/o title bar
5 - Menu Style a la Professional Write
6 - Edge Border with title bar
7 - Chisel Raised
8 - Chisel Sunken
9 - Notepad
}
procedure Box(X1,Y1,X2,Y2,FB,style:byte);
{draws box and leaves internal area as is}
const
Style0:string[8] = ' ';
Style1:string[8] = '│┌─┐│└─┘';
Style2:string[8] = '║╔═╗║╚═╝';
Style4:string[8] = chr(189)+chr(201)+chr(202)+chr(200)+chr(204)+chr(198)+chr(203)+chr(199);
var
Line,
FLine:string;
Str: string[8];
I: integer;
procedure DrawTheRest;
{}
var I: integer;
begin
for I := succ(Y1) to pred(Y2) do
begin
WriteAt(X1,I,FB,Str[1]);
WriteAt(X2,I,FB,Str[5]);
end;
WriteAt(X1,Y2,FB,Str[6]);
WriteAt(X1+1,Y2,FB,replicate(pred(X2-X1),Str[7]));
WriteAt(X2,Y2,FB,Str[8]);
end; { DrawTheRest }
begin
if (not FastVars.CustomCharsActive and (Style = 4))
or (FastVars.CustomCharsActive and (Style = 2)) then
Style := 1;
case Style of
0,1,
2,4:begin
case Style of
0: Str := Style0;
1: Str := Style1;
2: Str := Style2;
else Str := Style4;
end; {case}
{draw first line of the box}
WriteAt(X1,Y1,FB,Str[2]);
WriteAt(X1+1,Y1,FB,replicate(pred(X2-X1),Str[3]));
WriteAt(X2,Y1,FB,Str[4]);
DrawTheRest;
end;
3:begin
WriteAT(X1,Y1,FB,replicate(succ(X2-X1),' '));
end;
5:begin
ClearText(X1,Y1,X2,Y2,FB);
WriteAT(X1,Y1,FB,replicate(X2-pred(X1),char(223)));
WriteAT(X1,Y1+2,FB,replicate(X2-pred(X1),'─'));
end;
6:begin
if FastVars.CustomCharsActive then
Str := Style4
else
Str := Style1;
WriteAT(X1,Y1,FB,replicate(succ(X2-X1),' '));
DrawTheRest;
end;
7:begin
Box3D(X1,Y1,X2,Y2,Cattr(15,Battr(FB)),Cattr(0,Battr(FB)),1);
end;
8:begin
Box3D(X1,Y1,X2,Y2,Cattr(0,Battr(FB)),Cattr(15,Battr(FB)),1);
end;
9:begin
ClearText(X1,Y1,X2,Y2,FB);
for I := X1 to X2 do
if not odd(I) then
WriteAt(I,Y1+3,Cattr(black,bAttr(FB)),'─')
else
WriteAt(I,Y1+3,15,'('); { white,black }
end;
else
begin
Str := replicate(8,chr(Style));
WriteAt(X1,Y1,FB,replicate(succ(X2-X1),Str[1]));
WriteAt(X1,Y2,FB,replicate(succ(X2-X1),Str[1]));
for I := succ(Y1) to pred(Y2) do
begin
WriteAt(X1,I,FB,Str[1]);
WriteAt(X2,I,FB,Str[5]);
end;
end;
end; {case}
end; { Box }
procedure FBox(X1,Y1,X2,Y2,FB,style:byte);
{draws box and erases internal area}
begin
Box(X1,Y1,X2,Y2,FB,Style);
case style of
3: ClearText(X1,succ(Y1),X2,Y2,FB);
5: begin
ClearText(X1,succ(Y1),X2,succ(Y1),FB);
ClearText(X1,Y1+3,X2,Y2,FB);
end;
7,8: ClearText(X1+2,succ(Y1),X2-2,succ(Y1),FB);
9:;
else ClearText(succ(X1),succ(Y1),pred(X2),pred(Y2),FB);
end; {case}
end; { FBox }
procedure GrowFBox(X1,Y1,X2,Y2,FB,style:byte);
{draws box and erases internal area}
const
Stages = 4;
StartX = 3;
StartY = 3;
ClockTicksPerStage = 1;
var
Counter,TX1,TY1,TX2,TY2,XDelta,YDelta: integer;
LastTime, NewTime: longint;
begin
if (X2-X1) < StartX then
begin
TX2 := X2;
TX1 := X1;
end else
begin
XDelta := (X2-X1) div (Stages * 2);
if XDelta < 1 then
XDelta := 1;
TX2 := (X2 - X1) div 2 + X1 + 2;
TX1 := TX2 - 3; {needs a box 3 by 3 minimum}
end;
if (Y2-Y1) < StartY then
begin
TY2 := Y2;
TY1 := Y1;
end else
begin
YDelta := (Y2-Y1) div (Stages * 2);
if YDelta < 2 then
YDelta := 2;
TY2 := (Y2 - Y1) div 2 + Y1 + 2;
TY1 := TY2 - 3;
end;
LastTime := KeyGetTime;
NewTime := LastTime;
Counter := 0;
repeat
inc(Counter);
FBox(TX1,TY1,TX2,TY2,FB,Style);
if TX1 >= X1 then
dec(TX1,XDelta);
if TX1 < X1 then
TX1 := X1;
if TY1 >= Y1 then
dec(TY1,YDelta);
if TY1 < Y1 then
TY1 := Y1;
if TX2 <= X2 then
inc(TX2,XDelta);
if TX2 > X2 then
TX2 := X2;
if TY2 <= Y2 then
inc(TY2,YDelta);
if TY2 > Y2 then
TY2 := Y2;
if FastVars.GrowNoise then
sound(500+Counter*350);delay(5+Counter*5);nosound;
while NewTime < LastTime + ClockTicksPerStage do
NewTime := KeyGetTime;
LastTime := NewTime;
until (TX1 = X1) and (TY1 = Y1) and (TX2 = X2) and (TY2 = Y2);
FBox(X1,Y1,X2,Y2,FB,Style);
end; { GrowFBox }
procedure HorizLine(X1,X2,Y,FB,Style : byte);
var I: integer;
LineChar: char;
begin
case Style of
0 : LineChar := ' ';
2,4: LineChar := '═';
1,3: LineChar := '─';
else LineChar := Chr(Style);
end; {case}
WriteAt(X1,Y,FB,replicate(X2-X1+1,LineChar))
end; { HorizLine }
procedure VertLine(X,Y1,Y2,FB,Style:byte);
{}
var I: integer;
LineChar: char;
begin
case Style of
0 : LineChar := ' ';
2,4: LineChar := '║';
1,3: LineChar := '│';
else LineChar := Chr(Style);
end; {case}
for I := Y1 to Y2 do
WriteAt(X,I,FB,LineChar)
end; { VertLine }
procedure SmartVertLine(X,Y1,Y2,FB,Style:byte);
{draws box character and adjust any lines it overlays}
var I: integer;
LineStr: string[19];
TestCh, Ch: char;
StringOffset: byte;
function AdjacentChar(X,Y:byte): char;
{}
begin
if (X < 1) or (X > FastVars.Screen[FastVars.ActiveScreen]^.Width) then
AdjacentChar := ' '
else
AdjacentChar := ReadChar(X,Y);
end; { AdjacentChar }
function LineCh(X,Y:byte): char;
{}
const
LeftSingle: string[13] = '─┬┐┼┤┴┘╥╖╫╢╨╜';
LeftDouble: string[13] = '═╦╗╬╣╩╝╤╕╪╡╧╛';
RightSingle:string[13] = '┌─┬├┼└┴╓╥╟╫╙╨';
RightDouble:string[13] = '╔═╦╠╬╚╩╒╤╞╪╘╧';
var LineStyle: char;
begin
LineStyle := AdjacentChar(pred(X),Y);
if pos(LineStyle,RightSingle) > 0 then
LineStyle := '─'
else if pos(LineStyle,RightDouble) > 0 then
LineStyle := '═'
else
LineStyle := ' ';
case LineStyle of
'─': if pos(AdjacentChar(succ(X),Y),leftSingle) > 0 then
Ch := LineStr[2+StringOffset]
else
Ch := LineStr[3+StringOffset];
'═': if pos(AdjacentChar(succ(X),Y),LeftDouble) > 0 then
Ch := LineStr[4+StringOffset]
else
Ch := LineStr[5+StringOffset];
else TestCh := AdjacentChar(succ(X),Y);
If pos(TestCh,LeftSingle) > 0 then
Ch := LineStr[6+StringOffset]
else if pos(TestCh,LeftDouble) > 0 then
Ch := LineStr[7+StringOffset]
else
Ch := LineStr[1];
end; {case}
LineCh := Ch;
end; { LineCh }
begin
if Style in [2,4] then
LineStr := '║╥╖╦╗╓╔╫╢╬╣╟╠╨╜╩╝╙╚'
else
LineStr := '│┬┐╤╕┌╒┼┤╪╡├╞┴┘╧╛└╘';
{draw first character}
StringOffSet := 0;
WriteAt(X,Y1,FB,LineCh(X,Y1));
StringOffSet := 6;
for I := succ(Y1) to pred(Y2) do
WriteAt(X,I,FB,LineCh(X,I));
StringOffSet := 12;
WriteAt(X,Y2,FB,LineCh(X,Y2));
end; { SmartVertLine }
procedure SmartHorizLine(X1,X2,Y,FB,Style:byte);
{draws box character and adjust any lines it overlays}
var I: integer;
LineStr: string[19];
TestCh, Ch: char;
StringOffset: byte;
function AdjacentChar(X,Y:byte): char;
{}
begin
if (Y < 1) or (Y > FastVars.Screen[FastVars.ActiveScreen]^.Depth) then
AdjacentChar := ' '
else
AdjacentChar := ReadChar(X,Y);
end; { AdjacentChar }
function LineCh(X,Y:byte): char;
{}
const
DownSingle: string[13] = '┌┬┐│├┼┤╒╤╕╞╪╡';
DownDouble: string[13] = '╔╦╗║╠╬╣╓╥╖╟╫╢';
UpSingle: string[13] = '│├┼┤└┴┘╞╪╡╘╧╛';
UpDouble: string[13] = '║╠╬╣╚╩╝╟╫╢╙╨║';
var
LineStyle: char;
begin
LineStyle := AdjacentChar(X,pred(Y));
If pos(LineStyle,DownSingle) > 0 then
LineStyle := '│'
else if pos(LineStyle,DownDouble) > 0 then
LineStyle := '║'
else
LineStyle := ' ';
case LineStyle of
'│': if pos(AdjacentChar(X,succ(Y)),UpSingle) > 0 then
Ch := LineStr[2+StringOffset]
else
Ch := LineStr[3+StringOffset];
'║': if pos(AdjacentChar(X,succ(Y)),UpDouble) > 0 then
Ch := LineStr[4+StringOffset]
else
Ch := LineStr[5+StringOffset];
else TestCh := AdjacentChar(X,succ(Y));
If pos(TestCh,UpSingle) > 0 then
Ch := LineStr[6+StringOffset]
else if pos(TestCh,UpDouble) > 0 then
Ch := LineStr[7+StringOffset]
else
Ch := LineStr[1];
end; {case}
LineCh := Ch;
end; { LineCh }
begin
if Style in [2,4] then
LineStr := '═╞╘╠╚╒╔╪╧╬╩╤╦╡╛╣╝╕╗ '
else
LineStr := '─├└╟╙┌╓┼┴╫╨┬╥┤┘╢╜┐╖';
{draw first character}
StringOffSet := 0;
WriteAt(X1,Y,FB,LineCh(X1,Y));
StringOffSet := 6;
for I := succ(X1) to pred(X2) do
WriteAt(I,Y,FB,LineCh(I,Y));
StringOffSet := 12;
WriteAt(X2,Y,FB,LineCh(X2,Y));
end; { SmartHorizLine }
{***********************}
{** Shadow Routines **}
{***********************}
procedure DrawShadow(X1,Y1,X2,Y2:integer);
{}
begin
Attrib(succ(X2),succ(Y1),X2+ShadWidth,Y2+ShadDepth,ShadowAttr);
Attrib(X1+ShadWidth,succ(Y2),X2,Y2+ShadDepth,ShadowAttr);
end; { DrawShadow }
procedure OuterXY(var X1,Y1,X2,Y2: integer);
{Calculates the outer dimension when a window of dimenesion X1,Y1,X2,Y2
is drawn with a shadow - the shadow is assumed down and to the right}
begin
inc(X2,ShadWidth);
if X2 >= HardVars.Width then
X2 := HardVars.Width;
inc(Y2,ShadDepth);
if Y2 >= HardVars.Depth then
Y2 := HardVars.Depth;
end; { OuterXY }
{************************}
{** Display Routines **}
{************************}
procedure SetCondensed;
{sets to maximum number of display lines supported by the display system}
begin
if OnScreen and (HardVars.DisplayType in [EGAMono,EGACol,VGAMono,VGACol]) then
begin
TextMode(Lo(LastMode)+Font8x8);
HardVars.Depth := succ(Hi(WindMax));
if FastVars.Screen[0]^.Window.Y2 = 25 then
FastVars.Screen[0]^.Window.Y2 := HardVars.Depth;
FastVars.Screen[0]^.Depth := HardVars.Depth;
ActivateVirtualScreen(0);
end;
end; { SetCondensed }
procedure Set25;
{resets display back to 25 lines}
begin
if OnScreen and (HardVars.Depth <> 25) then
begin
TextMode(Lo(LastMode));
HardVars.Depth := succ(Hi(WindMax));
FastVars.Screen[0]^.Depth := HardVars.Depth;
if FastVars.Screen[0]^.Window.Y2 > 25 then
ResetWindow;
ActivateVirtualScreen(0);
end;
end; { Set25 }
procedure SetBlinking(On:boolean);
{}
var Regs: registers;
begin
with Regs do
begin
Ah := $10;
Al := $03;
if On then
Bl := 01
else
Bl := 00;
end;
Intr($10,Regs);
end; { SetBlinking }
{*******************}
{** Scroll Bars **}
{*******************}
procedure SetScrollChars(U,D,L,R,E,B:char);
{}
begin
with FastVars do
begin
UpArrowChar := U;
DownArrowChar := D;
LeftArrowChar := L;
RightArrowChar := R;
ElevatorChar := E;
BackgroundChar := B;
end;
end; { SetScrollChars }
procedure SetScrollDefaults;
{}
begin
SetScrollChars('','',char(27),char(26),'','░');
end; { SetScrollDefaults }
function GetHScrollBarElevator(X1,X2:byte;Current,Max:longint) : byte;
{Returns the Y coordinate of the Elevator position}
var X,LineLength: integer;
begin
if Current > Max then
Current := Max;
if (Current > 0) and (Max >= Current) then
begin
LineLength := X2 - succ(X1);
if LineLength > 0 then
begin
if Current >= Max then
X := pred(X2)
else
begin
X := (Current * LineLength) div Max;
if (X <= 0) or (Current = 1) then
X := succ(X1)
else
inc(X,succ(X1));
end;
end else
X := 0;
end else
X := 0;
GetHScrollBarElevator := X;
end; { GetHScrollBarElevator }
procedure WriteHScrollBar(X1,X2,Y,FB: byte; Current,Max: longint);
{}
var X,LineLength: integer;
begin
if Current > Max then
Current := Max;
WriteAT(X1,Y,FB,FastVars.LeftArrowChar);
WriteAT(X2,Y,FB,FastVars.RightArrowChar);
WriteAT(succ(X1),Y,FB,replicate(pred(X2-X1),FastVars.BackgroundChar));
if (Current > 0) and (Max >= Current) then
begin
LineLength := X2 - succ(X1);
if LineLength > 0 then
begin
X := (Current * LineLength) div Max;
if Current >= Max then
X := pred(LineLength);
if (X < 0) or (Current = 1) then
X := 0;
WriteAT(succ(X1) + X,Y,FB,FastVars.ElevatorChar);
end;
end;
end; { WriteHScrollBar }
function GetVScrollBarElevator(Y1,Y2:byte;Current,Max:longint) : byte;
{Returns the Y coordinate of the Elevator position}
var Y,LineLength: integer;
begin
if Current > Max then
Current := Max;
if (Current > 0) and (Max >= Current) then
begin
LineLength := Y2 - succ(Y1);
if LineLength > 0 then
begin
if Current >= Max then
Y := pred(Y2)
else
begin
Y := (Current * LineLength) div Max;
if (Y <= 0) or (Current = 1) then
Y := succ(Y1)
else
inc(Y,succ(Y1));
end;
end else
Y := 0;
end else
Y := 0;
GetVScrollBarElevator := Y;
end; { GetVScrollBarElevator }
procedure WriteVScrollBar(X,Y1,Y2,FB: byte; Current,Max: longint);
{}
var I,Y: integer;
begin
WriteAT(X,Y1,FB,FastVars.UpArrowChar);
WriteAT(X,Y2,FB,FastVars.DownArrowChar);
for I := succ(Y1) to pred(Y2) do
WriteAT(X,I,FB,FastVars.BackgroundChar);
Y := GetVScrollBarElevator(Y1,Y2,Current,Max);
if Y <> 0 then
WriteAT(X,Y,FB,FastVars.ElevatorChar);
end; { WriteVScrollBar }
{********************}
{** Push Buttons **}
{********************}
procedure DrawButton(X1,X2,Y,HiFB,FB:byte; Str:string);
{}
var SF,A,X: byte;
begin
WriteAt(X1,Y,FB,replicate(succ(X2-X1),' '));
(*
SF := (X2 - X1 + 1 - length(Strip('A',HiMarker,Str)));
if SF <> 0 then
X := X1 + SF div 2
else
*)
X := X1;
WriteHi(X,Y,HiFB,FB,Str);
{draw button shadow effect}
if ColorScreen then
SF := CAttr(black,BAttr(ReadAttr(succ(X1),succ(Y))))
else
SF := CAttr(darkgray,BAttr(ReadAttr(succ(X1),succ(Y))));
WriteAT(succ(X1),succ(Y),SF,replicate(succ(X2-X1),char(223)));
WriteAT(succ(X2),Y,SF,char(220));
end; { DrawButton }
procedure DrawButtonDown(X1,X2,Y,HiFB,FB:byte; Str:string);
{}
var SF,SB,A,X: byte;
begin
WriteAt(succ(X1),Y,FB,replicate(succ(X2-X1),' '));
X := succ(X1) + (X2 - X1 + 1 - length(Strip('A',HiMarker,Str))) div 2 ;
WriteHi(X,Y,HiFB,FB,Str);
FB := ReadAttr(succ(X1),succ(Y));
WriteAT(succ(X1),succ(Y),FB,replicate(succ(X2-X1),' '));
WriteAT(X1,Y,FB,' ');
end; { DrawButtonDown }
{*************}
{** Other **}
{*************}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
procedure GoldExitRoutine;
{}
begin
ExitProc := FastVars.ExitChain;
{$IFNDEF NOVGACHARS}
RemoveCustomChars;
{$ENDIF}
end; { ExitRoutine }
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
procedure ResetStartUpMode;
{resets monitor mode and cursor settings to the state they
were in at program startup}
begin
with FastVars do
begin
TextMode(StartMode);
CursorSize(StartTop,StartBot);
FastVars.CustomCharsActive := false;
end;
end; { ResetStartUpMode }
{$ENDIF} {NOVGACHARS}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
function FastEMsg(ECode:integer): string;
{}
begin
case Ecode of
1001: FastEMsg := 'Insufficient memory to initialize program';
1002: FastEMsg := 'Virtual page allocation error';
else
FastEMsg := 'Internal Fast error';
end; {case}
end; { FastEMsg }
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
procedure FastSetError(ECode:integer);
{}
{$IFOPT D+}
var Ch: char;
Msg: string;
{$ENDIF}
begin
FastVars.Ecode := ECode;
{$IFOPT D+} {if debug active display an error message and terminate}
if Ecode <> 0 then
begin
str(Ecode,Msg);
Msg := Msg+': '+FastVars.EMsgFunc(Ecode);
writeln(' GoldFast Error - ',Msg);
Halt;
end;
{$ENDIF}
end; { FastSetError }
function LastFastError: integer;
{}
begin
LastFastError := FastVars.ECode;
end; { LastFastError }
{******************************}
{** Miscellaneous Routines **}
{******************************}
function OnScreen:boolean;
{}
begin
OnScreen := FastVars.ActiveScreen = 0;
end; { OnScreen }
{*****************************}
{** External/ASM Routines **}
{*****************************}
{$IFOPT F-}
{$DEFINE FOFF}
{$F+}
{$ENDIF}
{$L GOLD}
procedure WinWrite(var WinImage; Width,X1,Y2,X2,Y2,X3,Y3,Attr:byte; st:String;WWIgnore:byte); external;
procedure WinPlain(var WinImage; Width,X1,Y2,X2,Y2,X3,Y3,Attr:byte; st:String;WWIgnore:byte); external;
procedure WinAttr(var WinImage; Width,X1,Y2,X2,Y2,X3,Y3,X4,Y4,Attr:byte;WWIgnore:byte); external;
procedure WinRedraw(MakeVisible:boolean); external;
procedure MoveToScreen(SourceY1,SourceX1,SourceY2,SourceX2,SourceWidth:byte;var SourcePtr;
TargetX,TargetY,TargetWidth:byte;var TargetPtr); external;
procedure MoveFromScreen(X1,Y1,X2,Y2,SourceWidth:byte; var SourcePtr, TargetPtr); external;
procedure TopWinRedraw; external;
procedure FillVideo(var Buffer; Count:word; Info:VideoWord); external;
function Different(var Source1,Source2;Size:word):boolean; external;
{$IFDEF FOFF}
{$F-}
{$UNDEF FOFF}
{$ENDIF}
{***********************}
{** Cursor Routines **}
{***********************}
procedure CursorFind(var X,Y,Top,Bot:byte);
{updates instance with visible Cursor details}
var Regs: registers;
begin
if (VideoTarget.TargetType = WinTarget) then
begin
X := WStructurePtr(VideoTarget.TargetPtr)^.Cursor.X;
Y := WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Y;
Top := WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Top;
Bot := WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Bot;
end else
if OnScreen then
begin
with Regs do
begin
Ax := $0F00; {get page in Bx}
intr($10,Regs);
Ax := $0300;
intr($10,Regs);
X := lo(Dx) + 1;
Y := hi(Dx) + 1;
Top := hi(Cx) and $0F;
Bot := lo(Cx) and $0F;
end;
end else
with FastVars.Screen[FastVars.ActiveScreen]^ do
begin
X := CursorX;
Y := CursorY;
Top := ScanTop;
Bot := ScanBot;
end;
end; { CursorFind }
procedure AbsGotoXY(X,Y : byte);
{Uses BIOS to move the cursor, ignoring any window settings}
var Regs: registers;
begin
with Regs do
begin
Ah := 2;
Dh := pred(Y);
Dl := pred(X);
Bh := 0;
end;
intr($10,Regs);
end; { AbsGotoXY }
procedure GotoXY(X,Y : byte);
{Positions cursor on display, in window, or on virtual screen}
var X1,Y1:integer;
begin
if (VideoTarget.TargetType = WinTarget) then
begin
WStructurePtr(VideoTarget.TargetPtr)^.Cursor.X := X;
WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Y := Y;
if VideoTarget.MoveCursor then
begin
X1 := WStructurePtr(VideoTarget.TargetPtr)^.X +pred(X);
if VideoTarget.WindowActive then
inc(X1,pred(VideoTarget.WX1));
Y1 := WStructurePtr(VideoTarget.TargetPtr)^.Y +pred(Y);
if VideoTarget.WindowActive then
inc(Y1,pred(VideoTarget.WY1));
if (X1 >= 1) and (X1 <= HardVars.Width)
and (Y1 >= 1) and (Y1 <= HardVars.Depth) then
AbsGotoXY(X1,Y1)
else
CursorAbsSize(0,0); {if cursor would be off screen, hide it}
end;
end else
if VideoTarget.MoveCursor then {visible screen is active}
begin
if VideoTarget.WindowActive then
AbsGotoXY(X+pred(VideoTarget.WX1),Y+pred(VideoTarget.WY1))
else
AbsGotoXY(X,Y);
end else {virtual screen - windows are ignored}
with FastVars.Screen[FastVars.ActiveScreen]^ do
begin
CursorX := X;
CursorY := Y;
end; {with}
end; { GotoXY }
procedure AbsWhereXY(var X,Y:byte);
{Uses BIOS to get the cursor position, ignoring any window settings}
var Regs: registers;
begin
with Regs do
begin
Ah := 3;
Bh := 0;
intr($10,Regs);
Y := succ(Dh);
X := succ(Dl);
end;
end; { AbsWhereXY }
function WhereX: byte;
{Returns the cursor position, on screen, in window or on virtual screen}
var X1,Y1: byte;
begin
if (VideoTarget.TargetType = WinTarget) then
WhereX := WStructurePtr(VideoTarget.TargetPtr)^.Cursor.X
else if VideoTarget.MoveCursor then {visible screen is active}
begin
AbsWhereXY(X1,Y1);
if VideoTarget.WindowActive then
WhereX := X1 + pred(VideoTarget.WX1)
else
WhereX := X1;
end else
WhereX := FastVars.Screen[FastVars.ActiveScreen]^.CursorX;
end; { WhereX }
function WhereY: byte;
{Returns the cursor position, on screen, in window or on virtual screen}
var X1,Y1: byte;
begin
if (VideoTarget.TargetType = WinTarget) then
WhereY := WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Y
else if VideoTarget.MoveCursor then {visible screen is active}
begin
AbsWhereXY(X1,Y1);
if VideoTarget.WindowActive then
WhereY := Y1 + pred(VideoTarget.WY1)
else
WhereY := Y1;
end else
WhereY := FastVars.Screen[FastVars.ActiveScreen]^.CursorY;
end; { WhereY }
procedure CursorAbsSize(T,B:byte);
{Sets the scan lines for the cursor regardless of active screen/window}
var Regs: registers;
begin
with Regs do
begin
AX := $0100;
if (T=0) and (B=0) then
CX := $2020
else
begin
(*
If you have an odd video bios and cursor changes
are strange, enable this next line.
mem[$40:$87] := mem[$40:$87] or $01; {get cursor ownership from BIOS}
*)
Ch := T;
Cl := B;
end;
intr($10,Regs);
end;
end; { CursorAbsSize }
procedure CursorPos(X,Y: integer);
{}
begin
if OnScreen then {visible screen is active}
AbsGotoXY(X,Y)
else
with FastVars.Screen[FastVars.ActiveScreen]^ do
begin
CursorX := X;
CursorY := Y;
end; {with}
end; { PosCursor }
procedure CursorSize(T,B:byte);
{}
var X1,Y1: integer;
begin
if (VideoTarget.TargetType = WinTarget) then
begin
WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Top := T;
WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Bot := B;
if VideoTarget.MoveCursor then
begin
{check to see if cursor is on screen}
X1 := WStructurePtr(VideoTarget.TargetPtr)^.X
+ pred(WStructurePtr(VideoTarget.TargetPtr)^.Cursor.X);
if VideoTarget.WindowActive then
inc(X1,pred(VideoTarget.WX1));
Y1 := WStructurePtr(VideoTarget.TargetPtr)^.Y
+ pred(WStructurePtr(VideoTarget.TargetPtr)^.Cursor.Y);
if VideoTarget.WindowActive then
inc(Y1,pred(VideoTarget.WY1));
if (X1 >= 1) and (X1 <= HardVars.Width)
and (Y1 >= 1) and (Y1 <= HardVars.Depth) then
CursorAbsSize(T,B);
end;
end else
if VideoTarget.MoveCursor then {visible screen is active}
CursorAbsSize(T,B)
else
with FastVars.Screen[FastVars.ActiveScreen]^ do
begin
ScanTop := T;
ScanBot := B;
end;
end; { CursorSize }
function CharHeight: integer;
{get height of text mode characters for cursor manipulation}
var Regs: registers;
begin
if OnScreen then
begin
case HardVars.DisplayType of
Mono: CharHeight := 14;
EGACol,
CGA : CharHeight := 8;
else
with Regs do
begin
Ah := $11;
Al := $30;
BX := $0;
Intr($10,Regs);
CharHeight := CX;
end; {with}
end; {case}
end else {virtual screen assume normal mode}
begin
if HardVars.DisplayType = Mono then
CharHeight := 14
else
CharHeight := 8;
end;
end; { CharHeight }
procedure CursorHalf;
{}
var Charsize: byte;
begin
CharSize := CharHeight;
CursorSize(CharSize div 2, pred(CharSize));
end; { CursorHalf }
procedure CursorFull;
{}
var Charsize: byte;
begin
CharSize := CharHeight;
CursorSize(0,CharSize);
end; { CursorFull }
procedure CursorOn;
{}
var Charsize: byte;
begin
CharSize := CharHeight;
CursorSize(CharSize-3, CharSize-2);
end; { CursorOn }
procedure CursorOff;
{}
begin
CursorSize(0,0);
end; { CursorOff }
{***********************}
{** Window Settings **}
{***********************}
procedure SetWindow(X1,Y1,X2,Y2: byte);
{Sets the local Window coordinates for a screen or a window}
procedure UpdateVideoTarget;
{}
begin
VideoTarget.WX1 := X1;
VideoTarget.WY1 := Y1;
VideoTarget.WX2 := X2;
VideoTarget.WY2 := Y2;
end; { UpdateVideoTarget }
begin
if (X1 <= X2)
and (X1 > 0)
and (Y1 <= Y2)
and (Y1 > 0) then {window coords seem reasonable}
begin
if (VideoTarget.TargetType = WinTarget) then
begin
with WStructurePtr(VideoTarget.TargetPtr)^ do
begin
if (X2 <= Width)
and (Y2 <= Depth) then
begin
WinX1 := X1;
WinY1 := Y1;
WinX2 := X2;
WinY2 := Y2;
UpdateVideoTarget;
end;
end; {with}
end else
begin
with FastVars.Screen[FastVars.ActiveScreen]^ do
begin
if (X2 <= Width)
and (Y2 <= Depth) then
begin
Window.X1 := X1;
Window.Y1 := Y1;
Window.X2 := X2;
Window.Y2 := Y2;
UpdateVideoTarget;
end;
end;
end;
end;
end; { SetWindow }
procedure ResetWindow;
{Sets the windows to the perimeter of the screen or window}
var D,W: byte;
begin
if (VideoTarget.TargetType = WinTarget) then
begin
with WStructurePtr(VideoTarget.TargetPtr)^ do
begin
W := Width;
D := Depth;
end;
end else
if OnScreen then
begin
W := HardVars.Width;
D := HardVars.Depth;
end else
begin
W := FastVars.Screen[FastVars.ActiveScreen]^.Width;
D := FastVars.Screen[FastVars.ActiveScreen]^.Depth;
end;
SetWindow(1,1,W,D);
end; { ResetWindow }
procedure SetWinIgnore(On:Boolean);
{}
begin
if (VideoTarget.TargetType = WinTarget) then
SetBitStatus(WStructurePtr(VideoTarget.TargetPtr)^.WinState,WinConfine,not On)
else
FastVars.Screen[FastVars.ActiveScreen]^.WindowIgnore := On;
VideoTarget.WindowActive := not On;
end; { SetWinIgnore }
function GetSetWinIgnore(On:Boolean):boolean;
{}
begin
if (VideoTarget.TargetType = WinTarget) then
GetSetWinIgnore := not GetBitStatus(WStructurePtr(VideoTarget.TargetPtr)^.WinState,WinConfine)
else
GetSetWinIgnore := FastVars.Screen[FastVars.ActiveScreen]^.WindowIgnore;
SetWinIgnore(On);
end; { GetSetWinIgnore }
{*************************}
{** Screen Management **}
{*************************}
procedure ActivateVirtualScreen(Page:word);
{Page of nil signifies the visible screen}
begin
if Page = 0 then
FastVars.ActiveScreen := 0
else if (Page <= MaxVScreens) and (FastVars.Screen[Page] <> nil) then
FastVars.ActiveScreen := Page
else
exit;
with VideoTarget do
begin
ScreenPtr := FastVars.Screen[Page]^.ScreenPtr;
Width := FastVars.Screen[Page]^.Width;
Depth := FastVars.Screen[Page]^.Depth;
WX1 := FastVars.Screen[Page]^.Window.X1;
WY1 := FastVars.Screen[Page]^.Window.Y1;
WX2 := FastVars.Screen[Page]^.Window.X2;
WY2 := FastVars.Screen[Page]^.Window.Y2;
with FastVars.Screen[Page]^ do
WindowActive := (WindowIgnore = false);
TargetType := ScreenTarget;
TargetPtr := FastVars.Screen[Page];
MoveCursor := Page = 0;
end;
end; { ActivateVirtualScreen }
procedure ActivateBackground;
{Directs all screen writing to the background when at least one
window is active. To make the write's visible, you must call WinDrawAll
having updated the background}
begin
if BackBuffer <> nil then
begin
with VideoTarget do
begin
ScreenPtr := BackBuffer;
Width := HardVars.Width;
Depth := HardVars.Depth;
WX1 := 1;
WY1 := 1;
WX2 := Width;
WY2 := Depth;
TargetType := ScreenTarget;
TargetPtr := nil;
MoveCursor := false;
end;
end;
end; { ActivateBackground }
procedure ActivateVisibleScreen;
{}
begin
ActivateVirtualScreen(0);
end; { ActivateVisibleScreen }
procedure AllocateVirtualScreen(Page,X,Y:byte);
{INTERNAL - called by CreateScreen and SaveScreen}
begin
{if there is already a saved screen of different dimensions - get rid of it}
if ((FastVars.Screen[Page] <> nil)
and ( X*Y
<>
FastVars.Screen[Page]^.Depth * FastVars.Screen[Page]^.Width)
) then
DisposeScreen(Page);
if FastVars.Screen[Page] = nil then {need to allocate memory}
begin
if GoldMaxAvail > sizeof(FastVars.Screen[Page]^) then
begin
getmem(FastVars.Screen[Page],sizeof(FastVars.Screen[Page]^));
if GoldMaxAvail < X*Y*2 then
begin
{some memory error}
freemem(FastVars.Screen[Page],sizeof(FastVars.Screen[Page]^));
FastVars.Screen[Page] := nil;
FastSetError(1002);
end;
if Page <> 0 then
getmem(FastVars.Screen[Page]^.ScreenPtr,X*Y*2);
end else
FastSetError(1001);
end;
end; { AllocateVirtualScreen }
procedure CreateScreen(Page,X,Y,FB:byte);
{}
var OriginalTarget:VideoZone;
Attr:byte;
begin
if (Page <= MaxVScreens) then
begin
AllocateVirtualScreen(Page,X,Y);
if FastVars.Screen[Page] <> nil then
begin
with FastVars.Screen[Page]^ do
begin
CursorFind(CursorX,CursorY,ScanTop,ScanBot); {Save Cursor posn. and shape}
Depth := Y;
Width := X;
Window.X1 := 1;
Window.Y1 := 1;
Window.X2 := X;
Window.Y2 := Y;
CursorX := 1;
CursorY := 1;
OriginalTarget := VideoTarget;
ActivateVirtualScreen(Page);
CursorOn;
FillScreen(1,1,X,Y,FB,' ');
VideoTarget := OriginalTarget;
end;
end;
end;
end; { CreateScreen }
procedure SaveScreen(Page:byte);
{Save screen image and cursor details}
var MVisible: boolean;
begin
if (Page <= MaxVScreens) then
begin
AllocateVirtualScreen(Page,FastVars.Screen[0]^.Width,FastVars.Screen[0]^.Depth);
with FastVars.Screen[Page]^ do
begin
CursorFind(CursorX,CursorY,ScanTop,ScanBot); {save Cursor posn. and shape}
{save window settings}
Window := FastVars.Screen[0]^.Window;
Depth := HardVars.Depth;
Width := HardVars.Width;
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
MoveFromScreen(1,1,Width,Depth,Width,HardVars.ScreenPtr^,ScreenPtr^);
if MVisible then
MouseShow(true);
end;
end;
end; { SaveScreen }
procedure PartRestoreScreen(Page,X1,Y1,X2,Y2,X,Y:byte);
{Move from heap to screen, part of saved screen}
var MVisible: boolean;
begin
if FastVars.Screen[Page] <> nil then
begin
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
with FastVars.Screen[Page]^ do
MoveToScreen(X1,Y1,X2,Y2,width,ScreenPtr^,X1,Y1,HardVars.Width,HardVars.ScreenPtr^);
if MVisible then
MouseShow(true);
end;
end; { PartRestoreScreen }
procedure RestoreCursAndWin(Page:byte);
{INTERNAL}
begin
ActivateVisibleScreen;
with FastVars.Screen[Page]^ do
begin
CursorPos(CursorX,CursorY);
CursorSize(ScanTop,ScanBot);
with Window do
SetWindow(X1,Y1,X2,Y2);
end;
end; { RestoreCursAndWin }
procedure RestoreScreen(Page:byte);
{display a screen that was previously saved}
var Wid,Dep: integer;
MVisible: boolean;
begin
if (Page > 0) and (Page <= MaxVScreens)
and (FastVars.Screen[Page] <> nil) then
begin
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
if HardVars.Width = FastVars.Screen[Page]^.Width then {one big move}
with FastVars.Screen[Page]^ do
MoveToScreen(1,1,width,depth,width,ScreenPtr^,1,1,HardVars.Width,HardVars.ScreenPtr^)
else
begin
Wid := HardVars.Width;
if Wid >= FastVars.Screen[Page]^.Width then
Wid := FastVars.Screen[Page]^.Width;
Dep := HardVars.Width;
if Dep >= FastVars.Screen[Page]^.Depth then
Dep := FastVars.Screen[Page]^.Depth;
PartRestoreScreen(Page,1,1,Wid,Dep,1,1);
end;
if MVisible then
MouseShow(true);
RestoreCursAndWin(Page);
end;
end; { RestoreScreen }
procedure PartSlideRestoreScreen(Page:byte;Way:gDirection;X1,Y1,X2,Y2:byte);
{}
var I: integer;
begin
case Way of
Up:begin
for I := Y2 downto Y1 do
begin
PartRestoreScreen(Page,X1,Y1,X2,Y1+Y2-I,X1,I);
Delay(25);
end;
end;
Down:begin
for I := Y1 to Y2 do
begin
PartRestoreScreen(Page,X1,Y1+Y2 -I,X2,Y2,X1,Y1);
Delay(25); {savor the moment!}
end;
end;
Left:begin
for I := X1 to X2 do
begin
PartRestoreScreen(Page,X1,Y1,I,Y2,X1+X2-I,Y1);
end;
end;
Right:begin
for I := X2 downto X1 do
begin
PartRestoreScreen(Page,I,Y1,X2,Y2,X1,Y1);
end;
end;
Vert:for I := Y1 to Y1 + (Y2 - Y1) div 2 do
begin
PartRestoreScreen(Page,X1,I,X2,I,X1,I);
PartRestoreScreen(Page,X1,Y2+Y1-I,X2,Y2+Y1-I,X1,Y2+Y1-I);
Delay(50);
end;
Horiz:for I := X1 to X1 + succ(X2 -X1) div 2 do
begin
PartRestoreScreen(Page,I,Y1,I,Y2,I,Y1);
PartRestoreScreen(Page,(X2)+X1-I,Y1,(X2)+X1-I,Y2,(X2)+X1-I,Y1);
Delay(10);
end;
end; {case}
end; { PartSlideRestoreScreen }
procedure SlideRestoreScreen(Page:byte;Way:gDirection);
{}
var WinCoords: gByteCoords;
X,Y,Top,Bot : byte;
MVisible: boolean;
begin
X := HardVars.Width;
if X > FastVars.Screen[Page]^.Width then
X := FastVars.Screen[Page]^.Width;
Y := HardVars.Depth;
if Y > FastVars.Screen[Page]^.Depth then
Y := FastVars.Screen[Page]^.Depth;
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
PartSlideRestoreScreen(Page,Way,1,1,X,Y);
if MVisible then
MouseShow(true);
with FastVars.Screen[Page]^ do
begin
CursorPos(CursorX,CursorY);
CursorSize(ScanTop,ScanBot);
end;
{restore cursor details and window setting}
RestoreCursAndWin(Page);
end; { SlideRestoreScreen }
procedure DisposeScreen(Page:byte);
{Free memory and set pointer to nil}
begin
if (Page <= MaxVScreens) and (FastVars.Screen[Page] <> nil) then
begin
with FastVars.Screen[Page]^ do
freemem(ScreenPtr,Width*Depth*2);
freemem(FastVars.Screen[Page],sizeof(FastVars.Screen[Page]^));
FastVars.Screen[Page] := nil;
if FastVars.ActiveScreen = Page then
ActivateVirtualScreen(0);
end;
end; { DisposeScreen }
procedure PartSave (X1,Y1,X2,Y2:byte; var Dest);
{transfers data from active virtual screen to Dest}
var MVisible: boolean;
begin
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
with VideoTarget do
MoveFromScreen(X1,Y1,X2,Y2,Width,ScreenPtr^,Dest);
if MVisible then
MouseShow(true);
end; { PartSave }
procedure PartRestore (X1,Y1,X2,Y2:byte; var Source);
{restores data from Source and transfers to active virtual screen
- used internally}
var MVisible: boolean;
begin
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
with VideoTarget do
MoveToScreen(1,1,succ(X2-X1),succ(Y2-Y1),succ(X2-X1),Source,X1,Y1,width,ScreenPtr^);
if MVisible then
MouseShow(true);
end; { PartRestore }
procedure CopyScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
{copies text and attributes from one part of screen to another}
var S: word;
SPtr: pointer;
MVisible: boolean;
begin
S := succ(Y2-Y1)*succ(X2-X1)*2;
if GoldMaxAvail > S then
begin
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
getmem(SPtr,S);
PartSave(X1,Y1,X2,Y2,SPtr^);
PartRestore(X,Y,X+X2-X1,Y+Y2-Y1,SPtr^);
freemem(Sptr,S);
if MVisible then
MouseShow(true);
end;
end; { CopyScreenBlock }
procedure MoveScreenBlock(X1,Y1,X2,Y2,X,Y:byte);
{Moves text and attributes from one part of screen to another,
replacing with ReplaceChar}
const ReplaceChar = ' ';
var S: word;
SPtr: pointer;
I: Integer;
ST: string;
MVisible: boolean;
begin
S := succ(Y2-Y1)*succ(X2-X1)*2;
if GoldMaxAvail > S then
begin
MVisible := KeyVars.MouseVisible;
if MVisible then
MouseShow(false);
getmem(SPtr,S);
PartSave(X1,Y1,X2,Y2,SPtr^);
St := Replicate(succ(X2-X1),ReplaceChar);
for I := Y1 to Y2 do
WritePlain(X1,I,St);
PartRestore(X,Y,X+X2-X1,Y+Y2-Y1,SPtr^);
freemem(Sptr,S);
if MVisible then
MouseShow(true);
end;
end; { MoveScreenBlock }
procedure Scroll(Way:gDirection;X1,Y1,X2,Y2:byte);
{used for screen scrolling, uses Copy & WritePlain for speed}
const ReplaceChar = ' ';
var I: integer;
begin
case Way of
Up:begin
CopyScreenBlock(X1,succ(Y1),X2,Y2,X1,Y1);
WritePlain(X1,Y2,replicate(succ(X2-X1),ReplaceChar));
end;
Down:begin
CopyScreenBlock(X1,Y1,X2,pred(Y2),X1,succ(Y1));
WritePlain(X1,Y1,replicate(succ(X2-X1),ReplaceChar));
end;
Left:begin
CopyScreenBlock(succ(X1),Y1,X2,Y2,X1,Y1);
for I := Y1 to Y2 do
WritePlain(X2,I,ReplaceChar);
end;
Right:begin
CopyScreenBlock(X1,Y1,pred(X2),Y2,succ(X1),Y1);
for I := Y1 to Y2 do
WritePlain(X1,I,ReplaceChar);
end;
end; {case}
end; {Scroll}
{**********************}
{** Screen Writing **}
{**********************}
procedure WritePlain(X,Y:byte; St:string);
{}
var MVisible: boolean;
procedure WriteIt;
{}
begin
with VideoTarget do
begin
if not WindowActive then
WinPlain(ScreenPtr^,Width,1,1,width,depth,X,Y,0,St,0)
else
WinPlain(ScreenPtr^,Width,WX1,WY1,WX2,WY2,X,Y,0,St,0);
end;
end; { WriteIt }
begin
MVisible := OnScreen and KeyVars.MouseVisible;
with FastVars.Screen[FastVars.ActiveScreen]^ do
begin
if MVisible and MouseInZone(X,Y,X+length(St),Y) then
begin
MouseShow(false);
WriteIt;
MouseShow(true);
end else
WriteIt;
end;
end; { WritePlain }
procedure WriteAT(X,Y,FB:byte; St:string);
{}
var Attr: byte;
MVisible: boolean;
procedure WriteIt;
{}
begin
with VideoTarget do
begin
if not WindowActive then
WinWrite(ScreenPtr^,Width,1,1,width,depth,X,Y,FB,St,0)
else
WinWrite(ScreenPtr^,Width,WX1,WY1,WX2,WY2,X,Y,FB,St,0);
end;
end; { WriteIt }
begin
if X = 0 then
begin
WriteCenter(Y,FB,St);
exit;
end else
if Y = 0 then
begin
WriteMiddle(X,FB,St);
exit;
end;
if FB = Plain then
WritePlain(X,Y,St)
else
begin
if (FB = 0) then
FB := Tint[Fast];
MVisible := OnScreen and KeyVars.MouseVisible;
with FastVars.Screen[FastVars.ActiveScreen]^ do
begin
if MVisible and MouseInZone(X,Y,X+length(St),Y) then
begin
MouseShow(false);
WriteIt;
MouseShow(true);
end else
WriteIt;
end;
end;
end; { WriteAT }
procedure WinDrawAll;
{Turns off mouse and calls WinRedraw (ASM) }
begin
if KeyVars.MouseVisible then
begin
MouseShow(false);
WinRedraw(true);
MouseShow(true);
end else
WinRedraw(true);
FrontUpdated := true;
end; { WinDrawAll }
procedure WinDrawTop;
{Turns off mouse and calls TopWinRedraw (ASM) }
begin
if not FrontUpdated then
WinDrawAll
else if KeyVars.MouseVisible then
begin
MouseShow(false);
TopWinRedraw;
MouseShow(true);
end
else
TopWinRedraw;
end; { WinDrawTop }
procedure WriteCol(Col,Row:byte; St:string);
begin
with FastVars do
WriteAt(Col,Row,Tint[Fast],St);
end; { WriteCol }
procedure WriteCap(X,Y,FBCap,FB:byte;Str:string);
{Writes a string with the first capital letter in a different color}
var CapPos: byte;
begin
if Str <> '' then
begin
WriteAt(X,Y,FB,Str); {write whole string in default cols}
CapPos := 1;
while (CapPos <= length(Str))
and ((Str[CapPos] in [#65..#90]) = false) do
inc(CapPos);
if CapPos <= length(Str) then
WriteAt(X + pred(CapPos),Y,FBCap,Str[CapPos]);
end;
end; { WriteCap }
procedure WriteHi(X,Y,HiFB,FB:byte;Str:string);
{}
var P: byte;
Hi: boolean;
procedure WriteBit(Str:string);
begin
if Hi then
WriteAt(X,Y,HiFB,Str)
else
WriteAt(X,Y,FB,Str);
end; { WriteBit }
begin
Hi := False;
P := Pos(HiMarker,Str);
while P <> 0 do
begin
if P > 1 then
WriteBit(copy(Str,1,pred(P)));
delete(Str,1,P);
inc(X,pred(P));
P := Pos(HiMarker,Str);
Hi := not Hi;
end;
WriteBit(Str);
end; { WriteHi }
procedure WriteHiX2(X1,X2,Y,HiFB,FB:byte;Str:string);
{}
var
P: byte;
Hi: boolean;
MaxWidth,
CharCount: byte;
procedure WriteBit(Str:string);
begin
if CharCount + length(Str) > MaxWidth then
delete(Str,MaxWidth-CharCount,255);
if Hi then
WriteAt(X1,Y,HiFB,Str)
else
WriteAt(X1,Y,FB,Str);
end; { WriteBit }
begin
Hi := False;
MaxWidth := succ(X2-X1);
CharCount := 0;
P := Pos(HiMarker,Str);
while P <> 0 do
begin
inc(CharCount,pred(P));
if P > 1 then
WriteBit(copy(Str,1,pred(P)));
delete(Str,1,P);
inc(X1,pred(P));
P := Pos(HiMarker,Str);
Hi := not Hi;
end;
WriteBit(Str);
end; { WriteHiX2 }
procedure WriteClick(X,Y,FB:byte;Str:string);
{writes text to the screen with a click!}
var I: integer;
L : byte;
begin
L := length(Str);
if OnScreen then
for I := L downto 1 do
begin
WriteAt(X,Y,FB,copy(Str,I,succ(L-I)));
sound(500);delay(20);nosound;delay(30);
end
else
WriteAt(X,Y,FB,Str); {don't click if not visible}
end; { WriteClick }
procedure WriteHiCenter(Y,HiFB,FB:byte;Str:string);
{}
var X: integer;
TmpStr: string;
begin
with VideoTarget do
begin
TmpStr := Strip('A',HiMarker,Str);
if WindowActive then
X := (succ(WX2-WX1) - length(TmpStr)) div 2
else
X := (Width - length(TmpStr)) div 2;
inc(X);
if (X < 1) or (X > WX2) then
X := 1;
WriteHi(X,Y,HiFB,FB,Str);
end;
end; { WriteHiCenter }
procedure WriteCenter(Y,FB:byte;Str:string);
{}
var X: integer;
begin
with VideoTarget do
begin
if WindowActive then
X := (succ(WX2-WX1) - length(Str)) div 2
else
X := (Width - length(Str)) div 2;
inc(X);
if (X < 1) or (X > WX2) then
X := 1;
WriteAt(X,Y,FB,Str);
end;
end; { WriteCenter }
procedure WriteMiddle(X,FB:byte;Str:string);
{}
var X1,Y1,X2,Y2: byte;
Y: integer;
begin
with VideoTarget do
begin
if WindowActive then
Y := succ(WY2-WY1) div 2
else
Y := Depth div 2;
if Y < 1 then
Y := 1;
WriteAt(X,Y,FB,Str);
end;
end; { WriteMiddle }
procedure WriteBetween(X1,X2,Y,FB:byte;Str:string);
{}
var X: integer;
begin
if length(Str) >= X2 - X1 + 1 then
WriteAt(X1,Y,FB,Str)
else
begin
X := X1 + (X2 - X1 + 1 - length(Str)) div 2 ;
WriteAt(X,Y,FB,Str);
end;
end; { WriteBetween }
procedure WriteRight(X,Y,FB:byte;Str:string);
{writes a right-justified string to the screen}
var X1: integer;
begin
X1 := succ(X-length(Str));
if X1 < 1 then
WriteAT(1,Y,FB,last(pred(X),Str))
else
WriteAT(X1,Y,FB,Str);
end; { WriteRight }
procedure WriteVert(X,Y,FB:byte;Str:string);
{}
var L: byte;
I: integer;
begin
L := length(Str);
with VideoTarget do
begin
if WindowActive then
begin
if L > succ(WY2-WY1) - Y then
L := succ(WY2-WY1) - pred(Y);
end else
begin
if L > Depth - pred(Y) then
L := Depth - pred(Y);
end;
end;
for I := 1 to L do
WriteAt(X,Y-1+I,FB,Str[I]);
end; { WriteVert }
procedure WriteProgressEngine(X1,X2,Y:byte;PerCent:real;ShowPerCent:boolean);
{}
var PStr, TStr: StrScreen;
begin
with FastVars do
begin
PStr := Replicate((round((X2-X1)*PerCent)),ProgChar1);
TStr := Replicate(((X2-X1)-length(PStr)),ProgChar2);
WriteAT(X1,Y,TINT[Progress1],PStr);
WriteAT(X1+length(PStr),Y,TINT[Progress2],TStr);
if ShowPerCent then
WriteAT(X2+PerCentPad,Y,TINT[ProgressPercent],
PadRight(IntToStr(round(PerCent*100))+'%',4,' '));
end;
end;
procedure WriteProgressLong(X1,X2,Y:byte;Part,Total:longint;ShowPerCent:boolean);
{}
var TmpLong: real;
begin
if X2 > X1 then
begin
if Part > Total then
Part := Total;
TmpLong := (Part / Total);
WriteProgressEngine(X1,X2,Y,TmpLong,ShowPerCent);
end;
end; { WriteProgressLong }
procedure WriteProgressReal(X1,X2,Y:byte;Part,Total:extended;ShowPerCent:boolean);
{}
var TmpReal: real;
begin
if X2 > X1 then
begin
if Part > Total then
Part := Total;
TmpReal := (Part / Total);
WriteProgressEngine(X1,X2,Y,TmpReal,ShowPerCent);
end;
end; { WriteProgressReal }
procedure Attrib(X1,Y1,X2,Y2,FB:byte);
{changes color attrib at specified coords}
begin
with VideoTarget do
if KeyVars.MouseVisible then
begin
MouseShow(false);
if WindowActive then
WinAttr(ScreenPtr^,Width,WX1,WY1,WX2,WY2,X1,Y1,X2,Y2,FB,0)
else
WinAttr(ScreenPtr^,Width,1,1,Width,Depth,X1,Y1,X2,Y2,FB,0);
MouseShow(true);
end else
begin
if WindowActive then
WinAttr(ScreenPtr^,Width,WX1,WY1,WX2,WY2,X1,Y1,X2,Y2,FB,0)
else
WinAttr(ScreenPtr^,Width,1,1,Width,Depth,X1,Y1,X2,Y2,FB,0);
end;
end; { Attrib }
procedure FillScreen(X1,Y1,X2,Y2:byte; FB:byte; C:char);
var I: integer;
S: string;
begin
S := Replicate(succ(X2-X1),C);
for I := Y1 to Y2 do
WriteAT(X1,I,FB,S);
end; { FillScreen }
procedure Clear(FB:byte; C:Char);
{}
begin
with FastVars.Screen[FastVars.ActiveScreen]^ do
FillScreen(1,1,Width,Depth,FB,C);
end; { Clear }
procedure PartClear(X1,Y1,X2,Y2:byte; FB:byte; C:char);
{}
begin
FillScreen(X1,Y1,X2,Y2,FB,C);
end; { PartClear }
procedure ClearText(X1,Y1,X2,Y2,FB:byte);
{}
var I: integer;
S: string;
begin
FillScreen(X1,Y1,X2,Y2,FB,' ');
end; { ClearText }
procedure ClearLine(Y,FB:integer);
begin
WriteAt(1,Y,FB,replicate(80,' '));
end; { ClearLine }
{**********************}
{** Screen Reading **}
{**********************}
procedure ReadWord(X,Y:byte;var Attr:byte; var Ch : char);
{INTERNAL = updates vars Attr and Ch with attribute and character
bytes in screen location (X,Y) of the active screen}
type
ScreenWordRec = record
Ch : char;
Attr : byte;
end;
var
VisibleAdr: word;
SW: ScreenWordRec;
MVisible:boolean;
begin
with VideoTarget do
begin
if WindowActive then
begin
inc(X,pred(WX1));
inc(Y,pred(WY1));
end;
VisibleAdr := pred(Y)*Width*2 + pred(X)*2;
MVisible := OnScreen and KeyVars.MouseVisible;
if not WindowActive and MVisible and MouseInZone(X,Y,X,Y) then
begin
MouseShow(false);
MoveFromScreen(X,Y,X,Y,Width,ScreenPtr^,SW);
MouseShow(true);
end else
MoveFromScreen(X,Y,X,Y,Width,ScreenPtr^,SW);
Attr := SW.Attr;
Ch := SW.Ch;
end;
end; { ReadWord }
function ReadChar(X,Y:byte):char;
var A: byte;
C: char;
begin
ReadWord(X,Y,A,C);
ReadChar := C;
end; { ReadChar }
function ReadAttr(X,Y:byte):byte;
var A: byte;
C: char;
begin
ReadWord(X,Y,A,C);
ReadAttr := A;
end; { ReadAttr }
function ReadStr(X1,X2,Y:byte):string;
var I: integer;
Str: string;
begin
Str := '';
for I := X1 to X2 do
Str := Str + ReadChar(I,Y);
ReadStr := Str;
end; { ReadStr }
{*********************************************}
{** U N I T I N I T I A L I Z A T I O N **}
{*********************************************}
procedure FastDefaultSettings;
{}
begin
LineWrap := false;
ShowNow := false;
ShadowType := 3;
ShadowAttr := 7;
BBTop := 0;
BBBot := 0;
with FastVars do
begin
GrowNoise := true;
ProgChar1 := '█'; {219}
ProgChar2 := '▒'; {177}
PerCentPad := 1;
end;
end; { FastDefaultSettings }
procedure GoldFastInit;
{}
var I: integer;
begin
SnowProne := HardVars.DisplayType = CGA;
ScreenLines := 25;
WinList := nil;
{$IFDEF DPMI}
getmem(FrontBuffer,8000);
{$ELSE}
FrontBuffer := ptr($BA00,$0000);
{$ENDIF}
with FastVars do
begin
for I := 0 to MaxVScreens
do Screen[I] := nil;
ActiveScreen := 0;
EMsgFunc := FastEMsg;
AllocateVirtualScreen(0,80,25);
StartMode := LastMode;
ActivateVisibleScreen;
CursorFind(StartX,StartY,StartTop,StartBot);
with Screen[0]^ do
begin
ScreenPtr := HardVars.ScreenPtr;
Width := 80;
Depth := HardVars.Depth;
Window.X1 := 1;
Window.Y1 := 1;
Window.X2 := 80;
Window.Y2 := Depth;
CursorX := 1;
CursorY := 1;
WindowIgnore := false;
end;
ActivateVisibleScreen;
CustomCharsActive := false;
ExitChain := ExitProc;
ExitProc := @GoldExitRoutine;
end;
FastDefaultSettings;
SetScrollDefaults;
end; { GoldFastInit }
{$IFDEF TTT5}
procedure PosCursor(X,Y: integer);
{}
begin
CursorPos(X,Y);
end; { PosCursor }
procedure FastWrite(Col,Row,Attr:byte; St:StrScreen);
{included for TTT5 compatibility}
begin
WriteAT(Col,Row,Attr,St);
end; { FastWrite }
procedure FWrite(St:StrScreen);
{included for TTT5 compatibility}
var Col,Row : byte;
begin
Col := WhereX;
Row := WhereY;
Fastwrite(Col,Row,attr(FCol,BCol),St);
GotoXY(Col+length(St),Row);
end; { FWrite }
procedure FWriteLN(St:StrScreen);
{included for TTT5 compatibility}
var Col,Row : byte;
begin
Col := WhereX;
Row := WhereY;
Fastwrite(Col,Row,attr(FCol,BCol),St);
GotoXY(1,succ(Row));
end; { FWriteLN }
function EGAVGASystem: boolean;
{included for TTT5 compatibility}
var Regs : registers;
begin
with Regs do
begin
Ax := $1C00;
Cx := 7;
Intr($10,Regs);
If Al = $1C then {VGA}
begin
EGAVGASystem := true;
exit;
end;
Ax := $1200;
Bl := $32;
Intr($10,Regs);
If Al = $12 then {MCGA}
begin
EGAVGASystem := true;
exit;
end;
Ah := $12;
Bl := $10;
Cx := $FFFF;
Intr($10,Regs);
EGAVGASystem := (Cx <> $FFFF); {EGA}
end; {with}
end; { EGAVGASystem }
procedure Reset_StartUp_Mode;
{included for TTT5 compatibility}
begin
ResetStartUpMode;
end; { Reset_StartUp_Mode }
procedure SetCondensedLines;
{included for TTT5 compatibility}
begin
SetCondensed;
end; { SetCondensedLines }
procedure Set25Lines;
{included for TTT5 compatibility}
begin
Set25;
end; { Set25Lines }
procedure Activate_Visible_Screen;
{included for TTT5 compatibility}
begin
ActivateVisibleScreen;
end; { Activate_Visible_Screen }
procedure Activate_Virtual_Screen(Page:byte);
{included for TTT5 compatibility}
begin
ActivateVirtualScreen(Page);
end; { Activate_Virtual_Screen }
function GetScreenChar(X,Y:byte):char;
{included for TTT5 compatibility}
begin
GetScreenChar := ReadChar(X,Y);
end; { GetScreenChar }
function GetScreenAttr(X,Y:byte):byte;
{included for TTT5 compatibility}
begin
GetScreenAttr := ReadAttr(X,Y);
end; { GetScreenAttr }
procedure GetScreenStr(X1,X2,Y:byte;var St:StrScreen);
{included for TTT5 compatibility}
begin
St := ReadStr(X1,X2,Y);
end; { GetScreenStr }
procedure PlainWrite(X,Y:byte; St:string);
{}
begin
WritePlain(X,Y,St);
end; { PlainWrite }
procedure FBAttrib(X1,Y1,X2,Y2,F,B:byte);
{}
begin
Attrib(X1,Y1,X2,Y2,Cattr(F,B));
end; { FBAttrib }
procedure FBClickwrite(Col,Row,F,B:byte; St:StrScreen);
{}
begin
WriteClick(Col,Row,Cattr(F,B),St);
end; { FBClickWrite }
procedure FBBox(X1,Y1,X2,Y2,F,B,boxtype:integer);
{}
begin
Box(X1,Y1,X2,Y2,Cattr(F,B),boxtype);
end; { FBBox }
procedure FBFBox(X1,Y1,X2,Y2,F,B,boxtype:integer);
{}
begin
FBox(X1,Y1,X2,Y2,Cattr(F,B),boxtype);
end; { FBFBox }
procedure FBGrowFBox(X1,Y1,X2,Y2,F,B,boxtype:integer);
{}
begin
GrowFBox(X1,Y1,X2,Y2,Cattr(F,B),boxtype);
end; { FBGrowFBox }
procedure FBHorizLine(X1,X2,Y,F,B,lineType:byte);
{}
begin
HorizLine(X1,X2,Y,Cattr(F,B),lineType);
end; { FBHorizLine }
procedure FBVertLine(X,Y1,Y2,F,B,lineType:byte);
{}
begin
VertLine(X,Y1,Y2,Cattr(F,B),lineType);
end; { FBVertLine }
procedure FBClearText(x1,y1,x2,y2,F,B:integer);
{}
begin
ClearText(x1,y1,x2,y2,Cattr(F,B));
end; { FBClearText }
procedure FBClearLine(Y,F,B:integer);
{}
begin
ClearLine(Y,Cattr(F,B));
end; { FBClearLine }
procedure FBWriteAT(X,Y,F,B:integer; St:StrScreen);
{}
begin
WriteAT(X,Y,Cattr(F,B),St);
end; { FBWriteAT }
procedure FBWriteBetween(X1,X2,Y,F,B:byte; St:StrScreen);
{}
begin
WriteBetween(X1,X2,Y,Cattr(F,B),St);
end; { FBWriteBetween }
procedure FBWriteCenter(LineNO,F,B:integer; St:StrScreen);
{}
begin
WriteCenter(LineNO,Cattr(F,B),St);
end; { FBWriteCenter }
procedure FBWriteVert(X,Y,F,B:integer; St:StrScreen);
{}
begin
WriteVert(X,Y,Cattr(F,B),St);
end; { FBWriteVert }
procedure FBFillScreen(X1,Y1,X2,Y2:byte; F,B:byte; C:char);
{}
Begin
FillScreen(X1,Y1,X2,Y2,Cattr(F,B),C);
End; { FBFillScreen }
{$ENDIF}
begin
GoldFastInit;
end.